#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"

struct usermap {
  struct hlist_node hlist;
  unsigned char* name;
};

unsigned BKDRHash(unsigned char *str);

int main() {
  unsigned char names[3][8] = {"smith", "bob", "john"};
  struct hlist_head user_hash[16];
  struct usermap *tmp;
  unsigned i, key;
  for (i = 0; i < 16; i++) {
    INIT_HLIST_HEAD(&user_hash[i]);
  }
  for (i = 0; i < 3; i++) {
    tmp = malloc(sizeof *tmp);
    tmp->name = names[i];
    key = BKDRHash(names[i]) & 15;
    hlist_add_head(&tmp->hlist, &user_hash[key]);

    struct usermap *tpos = malloc(sizeof *tpos);
    struct hlist_node *pos = malloc(sizeof *pos);
    hlist_for_each_entry(tpos, pos, &user_hash[key], hlist) {
      printf("%2d: %-8s\n", key, tpos->name);
    }
    printf("------over-------\n");
  }
    struct usermap *tpos = malloc(sizeof *tpos);
    struct hlist_node *pos = malloc(sizeof *pos);

  while(1) {
  unsigned char *new_name = malloc(sizeof(unsigned char) * 8);
  printf("please input a name: ");
  scanf("%s", new_name);
  key = BKDRHash(new_name) & 15;
  if (user_hash[key].first == NULL) {
    tmp = malloc(sizeof *tmp);
    tmp->name = new_name;
    hlist_add_head(&tmp->hlist, &user_hash[key]);
    printf("%s add successfully.\n", new_name);
  } else {
    int flag = 0;
    hlist_for_each_entry(tpos, pos, &user_hash[key], hlist) {
      if (strcmp(tpos->name, new_name) == 0) {
        printf("%s already exist.\n", new_name);
        flag = 1;
        break;
      }
    }
    if (!flag) {
        tmp = malloc(sizeof *tmp);
        tmp->name = new_name;
        hlist_add_head(&tmp->hlist, &user_hash[key]);
        printf("%s add successfully.\n", new_name);
      }
  }
  printf("user_hash[%d]: ", key);
  hlist_for_each_entry(tpos, pos, &user_hash[key], hlist) {
    printf(" %-s ->", tpos->name);
  }
  printf(" NULL\n------over-------\n");

  for (i = 0; i < 16; i++) {
    printf("user_hash[%2d]: ", i);
    hlist_for_each_entry(tpos, pos, &user_hash[i], hlist) {
      printf(" %-s ->", tpos->name);
    }
    printf(" NULL\n");
  }
  printf("------over------\n");


  }

  return 0;
}

unsigned BKDRHash(unsigned char *str) {
  unsigned int seed = 131;
  unsigned int hash = 0;
  while (*str) {
    hash = hash * seed + (*str++);
  }
  return (hash & 0x7FFFFFFF);
}
